package com.skyinno.mrms.conf;

import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * Created by 
 */
//java配置是通过@Configuration 和@Bean来实现
//@Configuration标注在类上，相当于把该类作为spring的xml配置文件中的<beans>，作用为：配置spring容器(应用上下文)
@Configuration   
//开启ConfigurationProperties功能
@EnableConfigurationProperties({HibernateProperties.class})
@ConditionalOnMissingClass
public class ApplicationConfiguration {

    Logger logger = LoggerFactory.getLogger(this.getClass());
//    @Autowired
//    private FirstDataSourceProperties primaryDataSource;//注入主数据源
//    @Autowired
//    private SecondDataSourceProperties secondaryDataSource;//注入从数据源
    @Autowired
    private HibernateProperties hibernatePropertes;

    
    /**
     * 自动配置（Auto-configuration）是非侵入性的，任何时候你都可以定义自己的配置类来替换自动配置的特定部分。
     * 例如，如果你添加自己的DataSource bean，默认的内嵌数据库支持将不被考虑。
     */
    
    //主数据源
    @Bean(name = "primaryDataSource")
    @Qualifier("primaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.mrms")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    //从数据源
    @Bean(name = "secondaryDataSource")
    @Qualifier("secondaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.druid.second")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }


    @Bean(name = "sessionFactory")
    @ConditionalOnMissingBean
    public LocalSessionFactoryBean setSessionFactory(){
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        Properties properties = new Properties();
        properties.setProperty("hibernate.show_sql",String.valueOf(hibernatePropertes.isShowSql()));
        properties.setProperty("hibernate.use_sql_comments",String.valueOf(hibernatePropertes.getUseSqlComments()));
        properties.setProperty("hibernate.dialect",String.valueOf(hibernatePropertes.getDialect()));
        properties.setProperty("hibernate.use_outer_join",String.valueOf(hibernatePropertes.isUseOuterJoin()));
        properties.setProperty("hibernate.query.factory_class",String.valueOf(hibernatePropertes.getQuery().getFactoryClass()));
        properties.setProperty("hibernate.format_sql",String.valueOf(hibernatePropertes.isShowSql()));
        properties.setProperty("hibernate.hbm2ddl.auto",String.valueOf(hibernatePropertes.getHbm2ddl()));
        properties.setProperty("hibernate.query.substitutions",String.valueOf(hibernatePropertes.getQuery().getSubstitutions()));
        properties.setProperty("hibernate.query.jpaql_strict_compliance",String.valueOf(hibernatePropertes.getQuery().isJpaqlStrictCompliance()));
        properties.setProperty("hibernate.jdbc.fetch_size",String.valueOf(hibernatePropertes.getJdbc().getFetchSize()));
        properties.setProperty("hibernate.jdbc.batch_size",String.valueOf(hibernatePropertes.getJdbc().getBatchSize()));
        properties.setProperty("hibernate.jdbc.sql_exception_converter",String.valueOf(hibernatePropertes.getJdbc().getSqlExceptionConverter()));
        properties.setProperty("hibernate.jdbc.wrap_result_sets",String.valueOf(hibernatePropertes.getJdbc().isWrapResultSets()));
        properties.setProperty("hibernate.jdbc.use_streams_for_binary",String.valueOf(hibernatePropertes.getJdbc().isUseStreamsForBinary()));
        properties.setProperty("hibernate.jdbc.use_scrollable_resultset",String.valueOf(hibernatePropertes.getJdbc().isUseScrollableResultset()));
        properties.setProperty("hibernate.jdbc.factory_class",String.valueOf(hibernatePropertes.getJdbc().getFactoryClass()));
        properties.setProperty("hibernate.jdbc.use_get_generated_keys",String.valueOf(hibernatePropertes.getJdbc().isUseGetGeneratedKeys()));
        properties.setProperty("hibernate.cache.jndi",String.valueOf(hibernatePropertes.getCache().isJndi()));
        properties.setProperty("hibernate.cache.use_second_level_cache",String.valueOf(hibernatePropertes.getCache().isUseSecondLevelCache()));
        properties.setProperty("hibernate.cache.use_structured_entries",String.valueOf(hibernatePropertes.getCache().isUseStructuredEntries()));
        properties.setProperty("hibernate.cache.use_query_cache",String.valueOf(hibernatePropertes.getCache().isUseStructuredEntries()));
        properties.setProperty("hibernate.cache.use_minimal_puts",String.valueOf(hibernatePropertes.getCache().isUseQueryCache()));
        properties.setProperty("hibernate.cache.provider_class",String.valueOf(hibernatePropertes.getCache().getProviderClass()));
        properties.setProperty("hibernate.cache.provider_configuration_file_resource_path",String.valueOf(hibernatePropertes.getCache().getProviderConfigurationFileResourcePath()));
        properties.setProperty("hibernate.cache.query_cache_factory",String.valueOf(hibernatePropertes.getCache().getQueryCacheFactory()));
        properties.setProperty("hibernate.cache.region_prefix",String.valueOf(hibernatePropertes.getCache().getRegionPrefix()));

        sessionFactory.setHibernateProperties(properties);
        sessionFactory.setPackagesToScan(hibernatePropertes.getPackagesToScan());
        sessionFactory.setDataSource(primaryDataSource());
        return sessionFactory;
    }

    @Bean(name = "transactionManager")
    @ConditionalOnMissingBean
    public HibernateTransactionManager setHibernateTransactionManager(SessionFactory sessionFactory){
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory);
        return transactionManager;
    }

    @Bean(name = "primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(
            @Qualifier("primaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate secondaryJdbcTemplate(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    
}
